Cloudflare Accessで制限されたNocoBase APIにGoogle Colabからアクセスするにはどうすればいいですか
困っていたこと
NocoBaseへのアクセスにCloudflare Accessを利用し、Cloudflare WARPを経由しないと接続できないよう制限しています。
NocoBaseのAPIを使って処理を自動化したいのですが、これだとGoogle Colabからはアクセスできません。
信頼されたツールにAPIへのアクセスを許可することはできますか。
どう対応すればいいの?
Cloudflare Accessに次の設定を追加することで、信頼されたツールからAPIへのアクセスを許可することが可能です。
ポイント
- パス /api を画面とは別のアプリケーションとして定義する
- API用のアプリケーション設定に、 Service Token が設定されている場合はアクセスを許可するポリシーを付与する
- APIクライアントのHTTPリクエストヘッダーに Service Token を付与してAPIにアクセスする
1. Service Tokenを発行する
CloudflareでService Tokenを発行します。画面付きの詳しい手順は下記ブログを参考にしてください。
Cloudflare Zero Trustのダッシュボードone.dash.cloudflare.com 画面から、Access → Service Authを開きます。
Create Service Tokenボタンをクリックし、新たにトークンを発行します。
表示されたClient IDとClient Secretを大事に保管しておきます。特にClient Secret はこの画面を離れると再度確認する画面はありませんので注意してください。
2. Applicationのポリシーを設定する
APIアクセス用のアプリケーションを作成します。画面付きの詳しい手順は下記ブログを参考にしてください。
Cloudflare Zero Trustのダッシュボードone.dash.cloudflare.com 画面から、Access → Applications を開きます。
"Application domain"のPathを api
としてAPIアクセス時にこの設定が適用されるようにしてください。
作成したアプリケーションの Policies タグから "Add a policy" ボタンをクリックします。
"Policy name"を入力し、"Action"に Service Auth
を選択します。
画面下の "Configuration rules" → "Include" で、"Selector" に Service Token
を、"Value" に先程作成したService Tokenを追加します。
3. Google Colabからアクセスする
Google Colabで作成するPythonコードについては以前に投稿したブログを参考にしてください。
Google Colab の画面左にあるシークレット(鍵のアイコン)に、CloudflareのService Tokenを追加します。
- CLOUDFLARE_CLIENT_ID
- CLOUDFLARE_CLIENT_SECRET
設定した値は次のPythonコードで取得できます。
from google.colab import userdata
userdata.get('CLOUDFLARE_CLIENT_ID')
userdata.get('CLOUDFLARE_CLIENT_SECRET')
python-nocobaseは私のGitHubリポジトリにあるので、下記コマンドでインストールします。
!pip install git+https://github.com/ueki-kazuki/python-nocobase
下記のPythonコードはコレクション(DBテーブル)を一覧表示します。client.session.headers
の CF-Access-Client-Id
と CF-Access-Client-Secret
に Service Token を設定しています。
from google.colab import userdata
from nocobase.exceptions import NocoBaseAPIError
from nocobase.nocobase import JWTAuthToken
from nocobase.infra.requests_client import NocoBaseRequestsClient
auth = JWTAuthToken(userdata.get("NOCOBASE_TOKEN"))
client = NocoBaseRequestsClient(auth, userdata.get("NOCOBASE_URL"))
# 追加
client.session.headers["CF-Access-Client-Id"] = userdata.get("CLOUDFLARE_CLIENT_ID")
client.session.headers["CF-Access-Client-Secret"] = userdata.get("CLOUDFLARE_CLIENT_SECRET")
for c in client.collections().list():
print(f'{c["name"]=}')
Service Token、 Policy、 HTTPリクエストヘッダーそれぞれが正しく設定できていれば、テーブル一覧が出力されます。